from robot.parsing.model import TestData
import firebrick
import rwb
import os
import wx

'''
rwbapp.Open("foo.tsv")
  -> obj = DataObjectFactory("foo.tsv")
     self.Publish("open", obj)

'''

# need to check for minimum version numbers of
# python and wxpython, and bail with an error
# message if there's a mismatch
#    if wx.VERSION <= (2,8,9):

class RWBApp(firebrick.FirebrickApp):
    module = rwb
    title = "RWB: The Robot Framework Workbench"
    settings = "settings.cfg"
    window_class = rwb.RWBWindow
    
    def __init__(self, *args, **kwargs):
        super(RWBApp, self).__init__(*args, **kwargs)

        self._scheduled_jobs = {}
        self._data_object_classes = {}
        self.open_objects = []
        self.Register(RobotDataObject)
        self.Register(TextFileDataObject)

    def Register(self, obj_class):
        if issubclass(obj_class, DataObject):
            for suffix in obj_class.suffixes:
                # a suffix may have more than one data object
                # class associated with it (for example, ".html"
                # is both a robot file and a plain text file)
                # So each suffix will be assigned a list of
                # classes; the head of the list is considered
                # to be the default
                suffixes = self._data_object_classes.setdefault(suffix, [])
                suffixes.append(obj_class)
        else:
            super(RWBApp, self).Register(obj_class)

    def Open(self, path, window=None):
        '''Open a file with the default editor based on file type'''
        (name, suffix) = os.path.splitext(path)

        if window is None:
            window = self._windows[0]

        wx.BeginBusyCursor()
        if suffix in ('.tsv','.txt','.html') or os.path.isdir(path):
            self.OpenRobotSuite(path, window)
        else:
            edit_panel = self.GetPanel(window, "rwb.core.edit_notebook")
            edit_panel.Open(FilePath(path))
        wx.EndBusyCursor()

    def OpenRobotSuite(self, path, window=None):
        '''Open a robot test suite'''
        suite = TestData(parent=None, source=path)
        self.Publish("open", suite=suite)
        
    def OpenTextFile(self, path, window=None):
        '''Open a plain text file'''
        edit_panel = self.GetPanel(window, "rwb.core.edit_notebook")
        edit_panel.Open(FilePath(path))

    def OpenAs(self, path, preferred_editor):
        '''I want to give the user the ability to open files with
        a specific editor. For example, open README.txt as a plain
        text file rather than a robot test suite
        '''
        raise Exception("not implemented yet")

    def RunSoon(self, func, *args):
        '''Run a job at a later date
        
        If the job is already on the queue don't add it again.

        This is used becaues wxPython sometimes runs stuff waaaaay
        too often (such as OnChange and OnStyleNeeded events)
        '''
        key = (func,) + args
        if key in self._scheduled_jobs and self._scheduled_jobs[key].IsRunning():
            self._scheduled_jobs[key].Restart()
        else:
            self._scheduled_jobs[key] = wx.CallLater(100, func, *args)

class FilePath(object):
    def __init__(self, path):
        self.path = path
        self.name = os.path.basename(path)

class DataObject(object):
    '''Abstract class that represents "something that can be opened"

    This means either a plain text file or a robot suite file or directory.
    '''
    suffixes = []
    def __init__(self, path):
        self.path = path
        self.suite = None
        rwb.app.log.info("opening '%s'" % path)

class RobotDataObject(DataObject):
    suffixes = (".tsv",".txt",".html")

    def __init__(self, path):
        super(RobotDataObject, self).__init__(path)
        self.suite = TestData(parent=None, source=path)
        
class TextFileDataObject(DataObject):
    suffixes = (".py",".xml", "")

    def __init__(self, path):
        super(self.__class__, self).__init__(path)
        # the file isn't actually opened here so we don't
        # end up with duplicate copies of the data. The 
        # editor is responsible for opening the file and 
        # reading the contents.

    def GetData(self):
        f = open(self.path, "r")
        data = read(f)
        close(f)
        return data

    def SetData(self,s):
        f = open(self.path, "w")
        f.write(s)
        close(f)

